<h1>
	Class System
</h1>

<div id="oo-classes" class="sect">
	<h2>
		JavaScript Classes
	</h2>
	<p>
		<p>
			JavaScript本身是基于原型的，这与普通基于类的编程语言相比，在实现继承的机制上有较大的出入。JavaScript中创建一个新类那便是修改了某个对象原型（prototype）的结果。Ext提供了许多简化这方面工作的函数。有关不同继承方案的讨论可参考
			<a
				href="http://ajaxian.com/archives/comparison-of-javascript-inheritance-mechanisms-proposal">这里</A>。
		</P>
	</p>
</div>

<div id="oo-extend" class="sect">
	<h2>
		Ext.extend
	</h2>
	<p>
		Ext支持以下类风格的编程行为：继承扩展（extend），重写（overrride）/直接覆盖。这意味着开发者可以根据需求加入自己的行为，创建自己的类，或者修改某些函数让其更加合适。

		<ul>
			<!-- Begin extend -->
			<li>
				<b>extend</b>
				<div>
					Ext.extend方法创建新一个类之定义。第一个参数是父类，第二个参数是属性/函数的列表。第二个参数加入到对象的prototype中extend过后，Ext.extend还会产生一个superclass的引用，在第二个例子中有演示。

					<br />
					<br />
					<pre>
Person = Ext.extend(Object, {
    constructor: function(first, last){
        this.firstName = first;
        this.lastName = last;
    }

    getName: function(){
        return this.firstName + ' ' + this.lastName;
    }
});

Developer = Ext.extend(Person, {
    getName: function(){
        if(this.isCoding){
            return 'Go Away!';
        }else{
            <span class="comment">// 访问父类的方法</span>
            return Developer.superclass.getName.call(this); 
        }
    }
});

var p = new Person(<span class="string">'John'</span>, <span
							class="string">'Smith'</span>);
alert(p.getName());
</pre>
				</div>
			</li>
			<!-- End extend -->

			<!-- Begin override -->
			<li>
				<b>override</b>
				<div>
					override方法也编辑、修改类的其中一种途径，不过本方法不会创建一个新类，而是对现有类予以修改其行为，第一个参数是要覆盖的类，第二个参数就是覆盖列表。override方法实际是修改类prototype的属性。

					<br />
					<br />
					<pre>
<span class="comment">// 我们已声明的Person类</span>
Ext.override(Person, {
    getName: function(){
        <span class="comment">// 覆盖了旧行为，这次last name排头</span>
        return this.lastName + ' ' + this.firstName; 
    }
});
</pre>
				</div>
			</li>
			<!-- End override -->
		</ul>
	</p>
</div>

<div id="oo-complex" class="sect">
	<h2>
		Prototype共享时注意的问题
	</h2>
	<p>
		当在类原型中的prototype放置某项成员时，即表示所有该类的实例都会使用该共享的prototype。除非您有特效的要求，否则不要在prototype的定义中放入非原始类型的成员（像{}、[]数组，就不是原始类型成员。补充：字符型，布字型，数值型是原始类型）。

		<pre>
MyClass = Ext.extend(Object, {
    <span class="comment">// 所有MyClass的实例都使用这{}，不会“按引用”复杂新一份出来。</span>
    baseParams: {}, 
    
    foo: function(){
        this.baseParams.bar = 'baz';
    }
});

Ext.onReady(function(){

    var a = new MyClass();
    var b = new MyClass();
    
    a.foo();
    <span class="comment">// a已影响b的baseParams </span>
    console.log(b.baseParams); 
});
</pre>
	</p>
</div>

<div id="oo-singletons" class="sect">
	<h2>
		单例（Singletons）
	</h2>
	<p>
		单例另一种较常见的说法是“模块设计模式”，如果某一个类静态方法较多，或者该类只须要实例化一次，那么采用单例的模式就很不错了。JavaScript的单例模式中，我们常常会创建私有JavaScript变量或通过高明的闭包手法建立私有的方法，以一段程序入口的范例代码就能说明多少问题。
	</p>
	<pre>
MyApp = function(){
    var data; <span class="comment">外部无法访问data，这是的私有成员</span>
    return {
        init: function(){
            <span class="comment">// 初始化程序</span>
        },
        
        getData: function(){
            return data;
        }
    };
}();
Ext.onReady(MyApp.init, MyApp);
</pre>
</div>

<div id="oo-observable" class="sect">
	<h2>
		Ext.util.Observable
	</h2>
	<p>
		<a href="http://en.wikipedia.org/wiki/Observer_pattern">观察者（Observable，或订阅者subscriber）模式</A>常用于对象间的解藕，方便清楚了解其它对象的状态。观察者使用事件的概念，当主题的状态有所改变，那么主题就会是触发事件。换言之，状态一改变，主题辖下的订阅者就会接收到通知。为达到如此的灵活性，实现解藕编的程模型，很多Ext类就从Observable继承。创建一个自定义事件的类定很简单：

	</p>
	<pre>
var MyClass = Ext.extend(Ext.util.Observable, {
    constructor: function(config){
        this.addEvents(<span class="string">'datachanged'</span>); <span
			class="comment">//  声明打算触发的事件</span>
        MyClass.constructor.call(this, config);
    },
    
    update: function(){
        <span class="comment">// 执行数据更新</span>
        <span class="comment">// 对订阅者送入我们指定的参数 </span>
        this.fireEvent(<span class="string">'datachanged'</span>, this, this.data.length); 
    }
});

<span class="comment">// 进行事件的订阅</span>
var c = new MyClass();
c.on(<span class="string">'datachanged'</span>, function(obj, num){
    <span class="comment">// react to the data changed event.</span>
});
</pre>
</div>


<div id="oo-namespaces" class="sect">
	<h2>
		命名空间（Namespaces）
	</h2>
	<p>
		命名空间对组织代码很方便，可在两方面体现其益处：其一是用了命名空间，很大程度避免了全局空间被污染的问题，污染全局的成员终究不是一个好习惯，例如Ext对象本身就是在全局空间的一个对象。要养成一个良好的习惯，就要把写好的类放进一个命名空间中，可以用你公司的名字或程序的名字决定命名；其二是有助规范好你的代码，把相类似的或相依赖的类都放在同一个名命空间中，也方便向其它开发者指明代码其意图。
	</p>
	<pre>
<span class="comment">// 两种方式都是一样的，后者的为佳。</span>
Ext.namespace(
   <span class="string">'MyCompany'</span>, 
   <span class="string">'MyCompany.Application'</span>, 
   <span class="string">'MyCompany.Application.Reports'</span>
);
Ext.namespace(<span class="string">'MyCompany.Application.Reports'</span>);
</pre>
</div>

